/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package org.oimwrapper.testers;

import Thor.API.Operations.tcFormDefinitionOperationsIntf;
import Thor.API.Operations.tcFormInstanceOperationsIntf;
import Thor.API.Operations.tcObjectOperationsIntf;
import Thor.API.Operations.tcProvisioningOperationsIntf;
import Thor.API.tcResultSet;
import com.thortech.util.logging.Logger;
import java.util.HashMap;
import java.util.Map;
import org.junit.Test;
import org.oimwrapper.connectors.OIMAdapterBase;
import org.oimwrapper.connectors.OIMRemoteClientBase;

/**
 *
 */
public class ClientProcessTester {
    
    private static final Logger logger = Logger.getLogger(ClientFormsTester.class.getName());

    private OIMAdapterBase apiBase;
    
    private tcProvisioningOperationsIntf provOps = null;
    private tcFormInstanceOperationsIntf formInstOps = null;
    private tcFormDefinitionOperationsIntf formDefOps = null;
    private tcObjectOperationsIntf objectOp = null;

    @Test
    public void mainTest()
    {
        logger.debug("Starting ");
        OIMRemoteClientBase tester = null;
        logger.debug("Logging In ");
        try {
            tester = new OIMRemoteClientBase();

            System.setProperty("XL.HomeDir", TesterConfig.XL_HomeDir);
            tester.setConnectionInfo(TesterConfig.XL_USERID);
            tester.connect();
            apiBase = tester.getUtils();
        } catch (Exception ex) {
            logger.error("Exception",ex);
            return;
        }

        logger.debug("Logged In! ");
        
        
        
        
        try
        {
            formInstOps = (tcFormInstanceOperationsIntf)apiBase.getUtility(Thor.API.Operations.tcFormInstanceOperationsIntf.class);
            formDefOps = (tcFormDefinitionOperationsIntf)apiBase.getUtility(Thor.API.Operations.tcFormDefinitionOperationsIntf.class);
            objectOp = (tcObjectOperationsIntf)apiBase.getUtility(Thor.API.Operations.tcObjectOperationsIntf.class);
            provOps = (tcProvisioningOperationsIntf)apiBase.getUtility(Thor.API.Operations.tcProvisioningOperationsIntf.class);
            
        }
        catch(Exception e)
        {
            logger.error("APIError",e);
            return;
        }
        
        /*
        long key = 4164l;
        long prockey = this.getApprovalProcessInstanceKey(key);
        long taskkey = this.getTaskKey(prockey, "GroupApproval", "Completed");
        Map mapper = this.getLastTaskApprover(taskkey);
        * 
        */
        
        getOpenProvisioningTasksPaged();
        getOpenProvisioningTasks();
        
        /*
        long processInstanceKey = 6153L;
        String taskName = "CreateUser";
        
        long taskKey = getTaskKey(processInstanceKey,taskName);
        runTask(taskKey,processInstanceKey);
        * 
        */
        
        
    }
    
    private void runTask(long taskKey,long processInstanceKey)
    {
        try
        {
            provOps.addProcessTaskInstance(taskKey,processInstanceKey);
        }
        catch(Exception e)
        {
            logger.error("APIError",e);
        }
    }
    
    
    private void getOpenProvisioningTasks()
    {
        try
        {
            tcResultSet rs = provOps.getAssignedOpenProvisioningTasks(1L, new HashMap(), new String[0]);
        }
        catch(Exception e)
        {
            logger.error("APIError",e);
        }
    }
    
    
    private void getOpenProvisioningTasksPaged()
    {
        String[] statusFilter = new String[]{"Pending","Rejected"};
        String[] orderBy = new String[]{"OTI.SCH_KEY"};
        boolean asc = true;
        int start = 1;
        int end = 100;
        
        boolean totalcount=true;
        try
        {
            tcResultSet rs = provOps.getAssignedOpenProvisioningTasksPaged(1L, new HashMap(), 
                                                                           statusFilter,
                                                                           start,end,
                                                                           orderBy,
                                                                           asc,totalcount);
        }
        catch(Exception e)
        {
            logger.error("APIError",e);
        }
    }
    
    /*
     * look thru the task history and find the last approver for this task.
     */
    private Map getLastTaskApprover(long taskKeyStr) {
        logger.debug("Printing Task History");

        String assignmentType = null;
        String assignmentId = null;
        Map returnMap = new HashMap();

        tcResultSet rs = null;
        try {
            rs = provOps.getTaskHistory(taskKeyStr);
            String[] headers = rs.getColumnNames();
            for (int i = 0; i < rs.getRowCount(); i++) {
                rs.goToRow(i);
                logger.debug("Printing Task History Row " + i);
                for(int c=0;c<headers.length;c++)
                {
                    logger.debug(headers[c] + ":" + rs.getStringValue(headers[c]));
                }
                
                
                String type = rs.getStringValue("Process Instance.Task History.Assign Type");
                logger.debug("Type:" + type);
                if (type != null && type.equalsIgnoreCase("Group")) {
                    String groupName = rs.getStringValue("Groups.Group Name");
                    logger.debug("groupName:" + groupName);
                    if (groupName != null && groupName.trim().length() > 0) {
                        assignmentType = "group";
                        assignmentId = groupName;
                    }
                }
                if (type != null && type.equalsIgnoreCase("User")) {
                    String userName = rs.getStringValue("Process Instance.Task Information.Assignee User ID");
                    logger.debug("userName:" + userName);
                    if (userName != null && userName.trim().length() > 0) {
                        assignmentType = "user";
                        assignmentId = userName;
                    }
                }
                
                
            }
            
            if (assignmentType != null && assignmentId != null)
            {
                
                returnMap.put("TYPE",assignmentType);
                returnMap.put("ID",assignmentId);
            }
            
            return returnMap;
            
        } catch (Exception e) {
            logger.error("Error getLastTaskApprover",e);
            return null;
        }

    }
    
    /*
     * get the process instance key of the approval process for this object
     */
    private long getApprovalProcessInstanceKey(long objectInstanceKey) {
        logger.debug("Printing Approval Process Info");

        try {
            
            tcResultSet rs = provOps.getApprovalProcessInformation(objectInstanceKey);

            // hope that there is only one of these
            for (int i = 0; i < rs.getRowCount(); i++) {
                rs.goToRow(i);

                String procKey = rs.getStringValue("Process Instance.Key");
                if (procKey != null) {
                    return Long.parseLong(procKey);
                }
            }
        } catch (Exception e) {
            logger.error("Error getApprovalProcessInstanceKey", e);
        }
        return 0l;
    }
    
    /*
     * get the last task key of this task/status
     */
    private long getTaskKey(long processInstanceKey,String taskName,String taskStatus) {

        tcResultSet rs = null;
        String taskKeyStr = null;
        long taskKey = 0l;
        
        try {
            rs = provOps.getProcessDetail(processInstanceKey);
            for (int i = 0; i < rs.getRowCount(); i++) {
                rs.goToRow(i);


                String name = rs.getStringValue("Process Definition.Tasks.Task Name");
                String status = rs.getStringValue("Status.Category");

                if (taskName.equalsIgnoreCase(name) && taskStatus.equalsIgnoreCase(status)) {
                    taskKeyStr = rs.getStringValue("Process Instance.Task Details.Key");
                    if (taskKeyStr != null && taskKeyStr.length() > 0) {
                        taskKey = Long.parseLong(taskKeyStr);
                        
                    }
                }

            }
            return taskKey;
        } catch (Exception e) {
            logger.error("Error getTaskKey ",e);
        }
        return 0l;
    }
    
    /*
     * get the last task key of this task/status
     */
    private long getTaskKey(long processInstanceKey,String taskName) {

        tcResultSet rs = null;
        String taskKeyStr = null;
        long taskKey = 0l;
        
        try {
            rs = provOps.getProcessDetail(processInstanceKey);
            for (int i = 0; i < rs.getRowCount(); i++) {
                rs.goToRow(i);


                String name = rs.getStringValue("Process Definition.Tasks.Task Name");
                String status = rs.getStringValue("Status.Category");
                logger.debug("TaskName:" + name + " Status:" + status);
                if (taskName.equalsIgnoreCase(name)) {
                    taskKeyStr = rs.getStringValue("Process Instance.Task Details.Key");
                    if (taskKeyStr != null && taskKeyStr.length() > 0) {
                        taskKey = Long.parseLong(taskKeyStr);
                        logger.debug("TaskKey:" + taskKey);
                    }
                }

            }
            return taskKey;
        } catch (Exception e) {
            logger.error("Error getTaskKey ",e);
        }
        return 0l;
    }

}
